<?php
/**
 * Created by PhpStorm.
 * User: zd
 * Date: 2018/8/14
 * Time: 10:18
 */

namespace app\api\controller\v1;

use app\api\controller\BaseController;
use app\api\validate\Count;
use app\api\model\Product as ProductModel;
use app\api\validate\IDMustBePositiveInt;
use app\api\validate\ProductCategoryParameter;
use app\api\validate\ProductParameter;
use app\api\validate\ProductRemoveParameter;
use app\api\validate\ProductUPorDownParameter;
use app\common\lib\Redis;
use app\lib\exception\CardException;
use app\lib\exception\ProductException;
use app\api\service\Token as TokenService;
use app\api\service\Product as ProductService;
use app\lib\exception\SuccessMessage;


class Product extends BaseController
{
    /**
     * 获取最近新品
     * @param int $count
     * @return mixed
     * @throws ProductException
     */
    public function getRecent($count = 15){
        (new Count())->goCheck();
        $result = ProductModel::getMostRecent($count);
        if ($result->isEmpty()){
            throw new ProductException();
        }
        $result = $result->hidden(['summary']);
        return $result;
    }

    /**
     * 获取分类商品
     * @param $id
     * @param $page
     * @return false|\PDOStatement|string|\think\Collection
     * @throws ProductException
     * @throws \app\lib\exception\TokenException
     * @throws \think\Exception
     */
    public function getAllInCategory($id,$page){
        (new ProductCategoryParameter())->goCheck();
        $t_id = TokenService::getCurrentTokenVar('manager_id');
        //缓存标签准备
        $tag = sprintf(config('cache.product_list'),$t_id,$id);
        $hash = sprintf(config('cache.product_hash'),$t_id);
        $service = new ProductService();
        //获取缓存
        $status =  $service->getCacheList($id,$t_id,$page,$count=10,$tag,$hash);
        if (!empty($status)){
            return json_encode($status);
        }
        $result = ProductModel::getProductAllInCategory($id,$t_id,$page,$count=10);
        if ($result->isEmpty()){
            throw new ProductException([
                'code'=> 201
            ]);
        }
        $service->saveToCacheList($hash,$t_id,$id,$tag,$result);//缓存数据
        return $result;
    }
    /**
     * 获取商品详情
     * @param $id
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws ProductException
     */
    public function getOne($id){
        (new IDMustBePositiveInt())->goCheck();
        //缓存
        $t_id = TokenService::getCurrentTokenVar('manager_id');
        $tag = sprintf(config('cache.product'),$t_id,$id);
        $status =  $this->getCache($tag);
        if ($status){
            return $status;
        }
        $result = ProductModel::getProductDetail($id);
        if (empty($result)){
            throw new ProductException([
                'code'=>200,
            ]);
        }
        $result = $result->toArray();
        if ( $result['property'] != null){
            $result['property']=json_decode($result['property']);
        }
        $this->saveToCache($tag,json_encode($result),3600);
        return json($result);
    }

    /**
     * 获取商品码
     * @param $w_id
     * @param $p_id
     * @return \think\response\Json
     * @throws CardException
     * @throws ProductException
     * @throws \app\lib\exception\MiniSuiteException
     * @throws \app\lib\exception\TokenException
     * @throws \think\Exception
     */
    public function getProductQRCode($w_id,$p_id){
        $t_id = TokenService::getCurrentTokenVar('manager_id');
        $product = new ProductService();
        $url = $product->getProductQRCode($w_id,$t_id,$p_id);
        if (null != $url){
            $data['error_code'] = 0;
            $data['url'] = config('setting.remote_img_url').$url;
            return json($data);
        }else{
            throw new CardException([
                'code'=>200,
                'mag'=>'获取商品码失败',
                'error_code'=>20011
            ]);
        }
    }

    /**
     * 根据条件查询商品(CRM)
     * @param $condition
     * @param $category
     * @return false|\PDOStatement|string|\think\Collection
     */
    public function getProductList($condition,$category){
        $manager_id = TokenService::getCurrentUid();
        $product = new  ProductService();
        $result  =  $product->getProductList($condition,$category,$manager_id);
        return $result;
    }

    /**
     * 获取商品详情(CMS)
     * @param $goods_id
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws ProductException
     */
    public function getProduct($goods_id){
        $product = new ProductService();
        $result = $product->getProduct($goods_id);
        if (empty($result)){
            throw new ProductException();
        }
        return json($result);
    }

    /**
     * 添加商品(CMS)
     * @return \think\response\Json
     * @throws ProductException
     */
    public function createProduct(){
        (new ProductParameter())->goCheck();
        $manager_id = TokenService::getCurrentUid();
        //清空缓存
        $dataArray = input('post.');
        $product = new  ProductService();
        $result =  $product->createProduct($dataArray,$manager_id);
        if (empty($result)){
            throw new ProductException([
                'code'=>400,
                'msg'=>'添加商品失败',
                'err_code'=>20001
            ]);
        }
        //缓存数据准备
        $tag = sprintf(config('cache.product_list'),$manager_id,$result->category_id);//缓存key
        $hash = sprintf(config('cache.product_hash'),$manager_id);
        $product->saveToCache($tag,$result,$manager_id,$result->category_id,$hash);//添加缓存
        return json(new SuccessMessage());
    }

    /**
     * 更新商品(CMS)
     * @return \think\response\Json
     * @throws ProductException
     */
    public function updateProduct(){
        (new ProductParameter())->goCheck();
        $manager_id = TokenService::getCurrentUid();
        $dataArray = input('post.');
        $product = new  ProductService();
        $result =  $product->updateProduct($dataArray,$manager_id);
        if (!$result){
            throw new ProductException([
                'code'=>400,
                'msg'=>'修改商品失败',
                'err_code'=>20002
            ]);
        }
        //缓存更新
        $hash = sprintf(config('cache.product_hash'),$manager_id);
        $tag = sprintf(config('cache.product'),$manager_id,$dataArray['category_id']);
        Redis::getInstance()->del(0,$hash);//删除缓存
        Redis::getInstance()->del(0,$tag);//删除缓存
        return json(new SuccessMessage());
    }

    /**
     * 删除商品(CMS)
     * @param $id
     * @return \think\response\Json
     * @throws ProductException
     */
    public function deleteProduct($id){
        (new IDMustBePositiveInt())->goCheck();
        $manager_id = TokenService::getCurrentUid();
        $product = new  ProductService();
        $data = \app\api\model\Product::get($id);
        $result = $product->deleteProduct($id);
        if (!$result){
            throw new ProductException([
                'code'=>400,
                'msg'=>'删除商品失败',
                'err_code'=>20003
            ]);
        }
        //删除商品缓存
        $hash = sprintf(config('cache.product_hash'),$manager_id);//hash标志
        $name = sprintf(config('cache.product'),$manager_id,$data->id);//商品缓存标志
        $listName =  sprintf(config('cache.product_list'),$manager_id,$data->category_id);//商品ID列表缓存标志
        Redis::getInstance()->del(0,$hash);//删除缓存
        Redis::getInstance()->del(0,$name);//删除缓存
        Redis::getInstance()->del(0,$listName);//删除缓存
        return json(new SuccessMessage());
    }

    /**
     * 商品移动分类(CMS)
     * @param $product
     * @param $category_id
     * @return \think\response\Json
     * @throws ProductException
     */
    public function removeProduct($product,$category_id){
        (new ProductRemoveParameter())->goCheck();
        $manager_id = TokenService::getCurrentUid();
        //查询商品信息
        $oldList = ProductModel::getProductListById($product);
        $products = new  ProductService();
        $result = $products->removeProduct($product,$category_id);
        if (!$result){
            throw new ProductException([
                'code'=>400,
                'msg'=>'移动商品失败',
                'err_code'=>20004
            ]);
        }
        //更新缓存
        $newList = ProductModel::getProductListById($product);//新的产品列表
        $hash = sprintf(config('cache.product_hash'),$manager_id);//商品hash缓存标志
        $products->updateCacheList($manager_id,$oldList,$newList,$hash);
        Redis::getInstance()->del(0,$hash);//删除缓存
        return json(new SuccessMessage());
    }

    /**
     * 商品批量上下架(CMS)
     * @param $product
     * @param $type
     * @return \think\response\Json
     * @throws ProductException
     */
    public function batchUPOrDown($product,$type){
        (new ProductUPorDownParameter())->goCheck();
        $manager_id = TokenService::getCurrentUid();
        $products = new  ProductService();
        $result = $products->batchUPOrDown($product,$type);
        if (!$result){
            throw new ProductException([
                'code'=>400,
                'msg'=>'商品上下架失败',
                'err_code'=>20005
            ]);
        }
        $List = ProductModel::getProductListById($product);//新的产品列表
        $hash = sprintf(config('cache.product_hash'),$manager_id);//商品hash缓存标志
        //更新缓存
        if ($type == 'up'){
            $newList = $List->toArray();
            $oldList = [];
        }else{
            $newList = [];
            $oldList = $List->toArray();
        }
        $products->updateCacheList($manager_id,$oldList,$newList,$hash);
        return json(new SuccessMessage());
    }

    /**
     * 删除商品详情图片(CMS)
     * @param $product_id
     * @param $img_id
     * @param $type
     * @throws ProductException
     */
    public function deleteImg($product_id,$img_id,$type){
        $products = new  ProductService();
        $result = $products->deleteImg($product_id,$img_id,$type);
        if (!$result){
            throw new ProductException([
                'code'=>400,
                'msg'=>'删除商品图片失败',
                'err_code'=>20006
            ]);
        }
    }

    /**
     * CRM
     * 更具用户获取商品列表
     * @param $id
     * @return \think\response\Json
     */
    public function getProductByUser($id,$page){
        (new IDMustBePositiveInt())->goCheck();
        TokenService::getCurrentUid();
        $t_id = TokenService::getCurrentTokenVar('t_id');
        $result = ProductModel::getProductAllInCategory($id,$t_id,$page,$count=10);
        if ($result->isEmpty()){
            $data['code'] = 2002;
            $data['content'] = '';
        }else{
            $data['code'] = 200;
            $data['content'] = $result;
        }
        return json($data);
    }
}